﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.ExtensibleStorage;
using FrontRoomCheck.Model;
using FrontRoomCheck.Properties;

namespace FrontRoomCheck.Utiltiy
{
	internal static class InsertDataToRoom
	{
		private static Schema CreateSchema(Document doc, string schemaGuid, object obj)
		{
			Guid guid = new Guid(schemaGuid);
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				Transaction transaction = new Transaction(doc, "CreateSchema");
				try
				{
					transaction.Start();
					SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
					Type type = obj.GetType();
					schemaBuilder.SetSchemaName(type.Name);
					foreach (PropertyInfo propertyInfo in type.GetProperties())
					{
						Type propertyType = propertyInfo.PropertyType;
						if (propertyType == typeof(string))
						{
							FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField(propertyInfo.Name, typeof(string));
						}
						else
						{
							FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField(propertyInfo.Name, propertyType);
							if (fieldBuilder.NeedsUnits())
							{
                                fieldBuilder.SetUnitType((UnitType)1);
							}
						}
					}
					schema = schemaBuilder.Finish();
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
			}
			return schema;
		}

		public static void WriteToElement(List<Element> elem, string schemaGuid, object obj)
		{
			if (elem.Count <= 0)
			{
				return;
			}
			Document document = elem[0].Document;
			Guid guid = new Guid(schemaGuid);
			Schema.Lookup(guid);
			List<object> list = new List<object>();
			if (obj is List<InsertData>)
			{
				List<InsertData> list2 = new List<InsertData>();
				list2 = (obj as List<InsertData>);
				using (List<InsertData>.Enumerator enumerator = list2.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						InsertData item = enumerator.Current;
						list.Add(item);
					}
					goto IL_110;
				}
			}
			if (obj is List<InsertArea>)
			{
				List<InsertArea> list3 = new List<InsertArea>();
				list3 = (obj as List<InsertArea>);
				using (List<InsertArea>.Enumerator enumerator2 = list3.GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						InsertArea item2 = enumerator2.Current;
						list.Add(item2);
					}
					goto IL_110;
				}
			}
			if (obj is List<InsertDoor>)
			{
				List<InsertDoor> list4 = new List<InsertDoor>();
				list4 = (obj as List<InsertDoor>);
				foreach (InsertDoor item3 in list4)
				{
					list.Add(item3);
				}
			}
			IL_110:
			Transaction transaction = new Transaction(document, "WriteExtensibleStorage");
			for (int i = 0; i < elem.Count; i++)
			{
				Schema schema = InsertDataToRoom.CreateSchema(document, schemaGuid, list[i]);
				if (schema != null && schema.SchemaName == list[i].GetType().Name)
				{
					try
					{
						transaction.Start();
						Entity entity = new Entity(schema);
						Type type = list[i].GetType();
						foreach (PropertyInfo propertyInfo in type.GetProperties())
						{
							Field field = schema.GetField(propertyInfo.Name);
							object value = propertyInfo.GetValue(list[i], null);
							Type propertyType = propertyInfo.PropertyType;
							if (propertyType.Name == "String")
							{
								entity.Set<string>(field, (string)value);
							}
							else if (propertyType.Name == "Double")
							{
                                entity.Set<double>(field, (double)value, (DisplayUnitType)12);
							}
							else if (propertyType.Name == "Int32")
							{
								entity.Set<int>(field, (int)value);
							}
							else if (propertyType.Name == "Boolean")
							{
								entity.Set<bool>(field, (bool)value);
							}
						}
						elem[i].SetEntity(entity);
						transaction.Commit();
					}
					catch (Exception)
					{
						transaction.RollBack();
					}
				}
			}
		}

		public static InsertData ReadFromElement<InsertData>(Element elem, string schemaGuid)
		{
			Type typeFromHandle = typeof(InsertData);
			Guid guid = new Guid(schemaGuid);
			InsertData insertData = (InsertData)((object)Activator.CreateInstance(typeFromHandle));
			Document document = elem.Document;
			Schema schema = Schema.Lookup(guid);
			if (schema != null && schema.SchemaName == typeof(InsertData).Name)
			{
				try
				{
					Entity entity = elem.GetEntity(Schema.Lookup(guid));
					if (entity != null && entity.Schema != null)
					{
						Type type = insertData.GetType();
						foreach (PropertyInfo propertyInfo in type.GetProperties())
						{
							Field field = schema.GetField(propertyInfo.Name);
							Type propertyType = propertyInfo.PropertyType;
							if (propertyType.Name == "String")
							{
								string value = entity.Get<string>(field);
								propertyInfo.SetValue(insertData, value, null);
							}
							else if (propertyType.Name == "Double")
							{
                                double num = entity.Get<double>(field, (DisplayUnitType)12);
								propertyInfo.SetValue(insertData, num, null);
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
			return insertData;
		}

		public static InsertArea ReadAreaFromElement<InsertArea>(Element elem, string schemaGuid)
		{
			Type typeFromHandle = typeof(InsertArea);
			Guid guid = new Guid(schemaGuid);
			InsertArea insertArea = (InsertArea)((object)Activator.CreateInstance(typeFromHandle));
			Document document = elem.Document;
			Schema schema = Schema.Lookup(guid);
			if (schema != null && schema.SchemaName == typeof(InsertArea).Name)
			{
				try
				{
					Entity entity = elem.GetEntity(Schema.Lookup(guid));
					if (entity != null && entity.Schema != null)
					{
						Type type = insertArea.GetType();
						foreach (PropertyInfo propertyInfo in type.GetProperties())
						{
							Field field = schema.GetField(propertyInfo.Name);
							Type propertyType = propertyInfo.PropertyType;
							if (propertyType.Name == "String")
							{
								string value = entity.Get<string>(field);
								propertyInfo.SetValue(insertArea, value, null);
							}
							else if (propertyType.Name == "Double")
							{
                                double num = entity.Get<double>(field, (DisplayUnitType)12);
								propertyInfo.SetValue(insertArea, num, null);
							}
							else if (propertyType.Name == "Int32")
							{
								int num2 = entity.Get<int>(field);
								propertyInfo.SetValue(insertArea, num2, null);
							}
							else if (propertyType.Name == "Boolean")
							{
								bool flag = entity.Get<bool>(field);
								propertyInfo.SetValue(insertArea, flag, null);
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
			return insertArea;
		}

		public static InsertDoor ReadDoorElement<InsertDoor>(Element elem, string schemaGuid)
		{
			Type typeFromHandle = typeof(InsertDoor);
			Guid guid = new Guid(schemaGuid);
			InsertDoor insertDoor = (InsertDoor)((object)Activator.CreateInstance(typeFromHandle));
			Document document = elem.Document;
			Schema schema = Schema.Lookup(guid);
			if (schema != null && schema.SchemaName == typeof(InsertDoor).Name)
			{
				try
				{
					Entity entity = elem.GetEntity(Schema.Lookup(guid));
					if (entity != null && entity.Schema != null)
					{
						Type type = insertDoor.GetType();
						foreach (PropertyInfo propertyInfo in type.GetProperties())
						{
							Field field = schema.GetField(propertyInfo.Name);
							Type propertyType = propertyInfo.PropertyType;
							if (propertyType.Name == "String")
							{
								string value = entity.Get<string>(field);
								propertyInfo.SetValue(insertDoor, value, null);
							}
							else if (propertyType.Name == "Double")
							{
                                double num = entity.Get<double>(field, (DisplayUnitType)12);
								propertyInfo.SetValue(insertDoor, num, null);
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
			return insertDoor;
		}

		private static Entity IsFrontRoom(Room room)
		{
			InsertDataToRoom.guid = new Guid(Resources.GUID);
			Schema schema = Schema.Lookup(InsertDataToRoom.guid);
			Entity entity = room.GetEntity(schema);
			if (entity != null)
			{
				return entity;
			}
			return null;
		}

		private static FrontRoomPacker RoomDataToPacker(Room room)
		{
			Type typeFromHandle = typeof(InsertData);
			InsertData insertData = (InsertData)Activator.CreateInstance(typeFromHandle);
			Entity entity = InsertDataToRoom.IsFrontRoom(room);
			Schema schema = Schema.Lookup(InsertDataToRoom.guid);
			try
			{
				if (InsertDataToRoom.IsFrontRoom(room) != null)
				{
					Type type = insertData.GetType();
					foreach (PropertyInfo propertyInfo in type.GetProperties())
					{
						Field field = schema.GetField(propertyInfo.Name);
						Type propertyType = propertyInfo.PropertyType;
						if (propertyType.Name == "String")
						{
							string value = entity.Get<string>(field);
							propertyInfo.SetValue(insertData, value, null);
						}
						else if (propertyType.Name == "Int32")
						{
							int num = entity.Get<int>(field);
							propertyInfo.SetValue(insertData, num, null);
						}
						else if (propertyType.Name == "Double")
						{
                            double num2 = entity.Get<double>(field, (DisplayUnitType)12);
							propertyInfo.SetValue(insertData, num2, null);
						}
						else if (propertyType.Name == "Boolean")
						{
							bool flag = entity.Get<bool>(field);
							propertyInfo.SetValue(insertData, flag, null);
						}
						else if (propertyType.Name == typeof(List<string>).Name)
						{
							IList<string> value2 = new List<string>();
							value2 = entity.Get<IList<string>>(field);
							propertyInfo.SetValue(insertData, value2);
						}
					}
				}
			}
			catch (Exception)
			{
			}
			return null;
		}

		private static Guid guid;
	}
}
